import os
import time
from typing import Optional, Dict, Any

import requests


class BarkNotifier:
    """Bark iOS push notifier.

    Environment variables:
      - BARK_SERVER: e.g. https://api.day.app  (your Bark server)
      - BARK_DEVICE_KEY: your device key from Bark app
      - BARK_GROUP: optional group name in Bark app
      - BARK_ICON: optional icon URL
    """

    def __init__(
        self,
        server: Optional[str] = None,
        device_key: Optional[str] = None,
        group: Optional[str] = None,
        icon: Optional[str] = None,
    ) -> None:
        self.server = (server or os.getenv("BARK_SERVER", "")).rstrip("/")
        self.device_key = device_key or os.getenv("BARK_DEVICE_KEY", "").strip()
        self.group = group or os.getenv("BARK_GROUP", "").strip() or None
        self.icon = icon or os.getenv("BARK_ICON", "").strip() or None

        if not self.server or not self.device_key:
            raise RuntimeError("BARK_SERVER and BARK_DEVICE_KEY must be set")

        self.push_url = f"{self.server}/{self.device_key}"

    def send_message(self, title: str, body: str, sound: Optional[str] = None, url: Optional[str] = None) -> None:
        payload: Dict[str, Any] = {"title": title, "body": body}
        if self.group:
            payload["group"] = self.group
        if self.icon:
            payload["icon"] = self.icon
        if sound:
            payload["sound"] = sound
        if url:
            payload["url"] = url

        backoff_seconds = 1.0
        for attempt in range(5):
            try:
                resp = requests.post(self.push_url, json=payload, timeout=10)
                if resp.status_code == 429:
                    time.sleep(backoff_seconds)
                    backoff_seconds *= 2
                    continue
                resp.raise_for_status()
                return
            except Exception:
                if attempt == 4:
                    raise
                time.sleep(backoff_seconds)
                backoff_seconds *= 2


